﻿using System;
using System.Collections.Generic;
using System.IO;
using EmbeddedSharp.Core.Function;
using EmbeddedSharp.Scripting.Function.IO;

namespace EmbeddedSharp.Scripting {
    public class ScriptingConsole {
        public virtual string Title {
            get { return "Embedded# Console"; }
        }

        public virtual string WelcomeMessage {
            get {
                return
                    "Embedded# Console\nCopyright 2009 Team Zove\nhttp://embeddedsharp.codeplex.com\nexit() to quit, help() for detail, and findfunc() to find or list functions\n";
            }
        }

        public static void Main(string[] args) {
            var console = new ScriptingConsole();
            console.Process(args);
        }

        public void Process(string[] args) {
            string fileName = string.Empty;
            var opt = new List<string>(args);

            ConsoleColor defaultColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Green;

            ScriptingObject vm = GetVirtualMachine();

            if (opt.Contains("-nomem")) {
            }
            if (!opt.Contains("-silent")) {
                Console.Title = Title;
                Console.WriteLine(WelcomeMessage);
            }
            if (opt.Contains("-file")) {
                fileName = Run(args, fileName, opt, vm);
            }
            if (opt.Contains("-stmt")) {
                int index = opt.IndexOf("-stmt");
                fileName = opt[index + 1];

                // TODO : place suitable call here  
                // vm.Execute(fileName);
            }
            if (args.Length == 0) {
                StartInterative(vm);
            }

            //Console.WriteLine(ex.Message);
            //ILogger logger = new EventLogger("Zove");
            //logger.WriteLog(ex);
            Console.ForegroundColor = defaultColor;
        }

        private static string Run(
            string[] args, string fileName,
            List<string> opt, ScriptingObject intp) {
            int index = opt.IndexOf("-file");
            fileName = opt[index + 1];
            if (!File.Exists(fileName)) {
                Console.WriteLine("File not found.");
            }

            var p = new string[args.Length - 1];
            for (; index < args.Length - 1; index++) {
                p[index] = args[index + 1];
            }

            try {
                // TODO : place the right call here
                // intp.Run(fileName, p);
            } catch (Exception ex) {
            }
            return fileName;
        }

        public static void StartInterative(ScriptingObject intp) {
            Console.Write("> ");

            while (true) {
                try
                {
                    string input = Console.ReadLine();
                    if(string.IsNullOrEmpty(input))
                    {
                     throw new NullReferenceException("Input cannot be empty.");   
                    }

                    string stmt = input.Trim();
                    object result = intp.Process(stmt);
                    Console.WriteLine("< {0}", Convert.ToString(result));
                } catch (TerminateException te) {
                    Console.WriteLine("Exit: " + te.Message);
                    break;
                } catch (ClearScreenException cse) {
                    Console.Clear();
                } catch (Exception ex) {
                    Console.WriteLine(ex.Message);
                }
                Console.Write("> ");
            }
        }

        /// <summary>
        /// Get scripting object
        /// </summary>
        /// <returns></returns>
        protected virtual ScriptingObject GetVirtualMachine() {
            return new ScriptingObject();
        }

        /// <summary>
        /// Process unkown file type here
        /// </summary>
        /// <param name="fileName"></param>
        protected virtual void Process(string fileName) {
            Console.WriteLine("Unknown file type");
        }
    }
}